package edu.sdjzu.exam.service.exam.impl;

import cn.dev33.satoken.stp.StpUtil;
import edu.sdjzu.exam.domain.exam.ExamAnswer;
import edu.sdjzu.exam.domain.exam.StudentGrade;
import edu.sdjzu.exam.dto.ExamAnswerSubmitDTO;
import edu.sdjzu.exam.mapper.exam.ExamAnswersMapper;
import edu.sdjzu.exam.mapper.exam.ExamQuestionsMapper;
import edu.sdjzu.exam.mapper.exam.StudentGradesMapper;
import edu.sdjzu.exam.service.exam.AutoGradingService;
import edu.sdjzu.exam.service.exam.ExamAnswerService;
import edu.sdjzu.exam.service.rocketmq.ExamResultProducer;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;

@Slf4j
@Service
@RequiredArgsConstructor
public class ExamAnswerServiceImpl implements ExamAnswerService {

    private final ExamAnswersMapper examAnswersMapper;
    private final ExamQuestionsMapper examQuestionsMapper;
    private final StudentGradesMapper studentGradesMapper;
    private final AutoGradingService autoGradingService;
    private final ExamResultProducer examResultProducer;
    @Override
    @Transactional
    public AutoGradingService.AutoGradingResult submitExamAnswers(ExamAnswerSubmitDTO submitDTO) {
        Long studentId = StpUtil.getLoginIdAsLong();
        Long examId = submitDTO.getExamId();
        
        log.info("学生提交考试答案 - 考试ID: {}, 学生ID: {}, sessionId: {}", examId, studentId, submitDTO.getSessionId());
        log.info("提交的答案数量: {}", submitDTO.getAnswers().size());

        // 1. 保存所有答案
        for (ExamAnswerSubmitDTO.AnswerDTO answerDTO : submitDTO.getAnswers()) {
            log.info("=== 开始处理答案提交 ===");
            log.info("查询参数 - examId: {}, studentId: {}, questionId: {}, sessionId: {}", 
                    examId, studentId, answerDTO.getQuestionId(), submitDTO.getSessionId());
            log.info("答案内容 - content: {}, filePath: {}", 
                    answerDTO.getAnswerContent(), answerDTO.getFilePath());
            
            // 先查找是否存在草稿记录（包括草稿和正式答案）
            ExamAnswer existingAnswer = examAnswersMapper.selectAnswerByExamStudentAndQuestion(
                    examId, studentId, answerDTO.getQuestionId(), submitDTO.getSessionId());
            
            log.info("数据库查询结果 - existingAnswer: {}", existingAnswer != null ? "存在" : "不存在");
            if (existingAnswer != null) {
                log.info("现有答案详情 - answerId: {}, isDraft: {}, content: {}, answerTime: {}", 
                        existingAnswer.getAnswerId(), existingAnswer.getIsDraft(), 
                        existingAnswer.getAnswerContent(), existingAnswer.getAnswerTime());
            }
            
            ExamAnswer answer;
            if (existingAnswer != null) {
                // 如果存在记录（无论是草稿还是正式答案），都更新为正式答案
                log.info("执行更新操作 - 将现有记录更新为正式答案");
                existingAnswer.setAnswerContent(answerDTO.getAnswerContent());
                existingAnswer.setFilePath(answerDTO.getFilePath());
                existingAnswer.setIsDraft(false); // 提交时设为正式答案
                existingAnswer.setAnswerTime(LocalDateTime.now());
                examAnswersMapper.updateExamAnswer(existingAnswer);
                
                answer = existingAnswer;
                log.info("更新完成 - 考试ID: {}, 学生ID: {}, 题目ID: {}, answerId: {}", 
                        examId, studentId, answerDTO.getQuestionId(), existingAnswer.getAnswerId());
            } else {
                // 如果不存在任何记录，创建新的正式答案
                log.info("执行插入操作 - 创建新的正式答案记录");
                answer = new ExamAnswer();
                answer.setSessionId(submitDTO.getSessionId());
                answer.setExamId(examId);
                answer.setStudentId(studentId);
                answer.setQuestionId(answerDTO.getQuestionId());
                answer.setAnswerContent(answerDTO.getAnswerContent());
                answer.setFilePath(answerDTO.getFilePath());
                answer.setIsDraft(false); // 直接创建为正式答案
                answer.setAnswerTime(LocalDateTime.now());
                
                log.info("准备插入的答案对象 - sessionId: {}, examId: {}, studentId: {}, questionId: {}, isDraft: {}", 
                        answer.getSessionId(), answer.getExamId(), answer.getStudentId(), 
                        answer.getQuestionId(), answer.getIsDraft());
                
                examAnswersMapper.insertExamAnswer(answer);
                log.info("插入完成 - 新生成的answerId: {}", answer.getAnswerId());
            }
            log.info("=== 答案处理完成 ===");
            log.info("");
            
            // 尝试发送消息队列通知（非核心功能，失败不影响提交）
            try {
                examResultProducer.sendExamResult(answer);
                log.debug("消息队列发送成功 - 答案ID: {}", answer.getAnswerId());
            } catch (Exception e) {
                log.warn("消息队列发送失败，但不影响考试提交 - 考试ID: {}, 学生ID: {}, 题目ID: {}, 错误: {}", 
                        examId, studentId, answerDTO.getQuestionId(), e.getMessage());
                // 消息队列失败不抛出异常，确保考试提交成功
            }
        }

        // 2. 触发自动判卷
        AutoGradingService.AutoGradingResult result = autoGradingService.autoGradeExam(examId, studentId);
        
        // 3. 新增持久化自动判卷结果到 student_grades 表
        updateInitialStudentGrade(examId, studentId, result);
        
        log.info("考试答案提交完成 - 考试ID: {}, 学生ID: {}, 自动判卷: {}, 人工判卷: {}", 
                examId, studentId, result.getAutoGradedQuestions(), result.getManualGradedQuestions());
        
        return result;
    }

    @Override
    @Transactional
    public void saveAnswerDraft(ExamAnswerSubmitDTO submitDTO) {
        Long studentId = StpUtil.getLoginIdAsLong();
        Long examId = submitDTO.getExamId();
        
        log.info("保存答案草稿 - 考试ID: {}, 学生ID: {}, sessionId: {}", examId, studentId, submitDTO.getSessionId());
        log.info("草稿答案数量: {}", submitDTO.getAnswers().size());

        for (ExamAnswerSubmitDTO.AnswerDTO answerDTO : submitDTO.getAnswers()) {
            log.info("=== 开始处理草稿保存 ===");
            log.info("草稿查询参数 - examId: {}, studentId: {}, questionId: {}, sessionId: {}", 
                    examId, studentId, answerDTO.getQuestionId(), submitDTO.getSessionId());
            
            // 检查是否已存在答案记录
            ExamAnswer existingAnswer = examAnswersMapper.selectAnswerByExamStudentAndQuestion(
                    examId, studentId, answerDTO.getQuestionId(), submitDTO.getSessionId());
            
            log.info("草稿查询结果 - existingAnswer: {}", existingAnswer != null ? "存在" : "不存在");
            if (existingAnswer != null) {
                log.info("现有草稿详情 - answerId: {}, isDraft: {}, content: {}", 
                        existingAnswer.getAnswerId(), existingAnswer.getIsDraft(), 
                        existingAnswer.getAnswerContent());
            }
            
            if (existingAnswer != null) {
                // 更新现有答案
                log.info("执行草稿更新操作");
                existingAnswer.setAnswerContent(answerDTO.getAnswerContent());
                existingAnswer.setFilePath(answerDTO.getFilePath());
                existingAnswer.setIsDraft(true);
                existingAnswer.setAnswerTime(LocalDateTime.now());
                examAnswersMapper.updateExamAnswer(existingAnswer);
                log.info("草稿更新完成 - answerId: {}", existingAnswer.getAnswerId());
            } else {
                // 创建新答案
                log.info("执行草稿插入操作");
                ExamAnswer answer = new ExamAnswer();
                answer.setSessionId(submitDTO.getSessionId()); // 设置session_id
                answer.setExamId(examId);
                answer.setStudentId(studentId);
                answer.setQuestionId(answerDTO.getQuestionId());
                answer.setAnswerContent(answerDTO.getAnswerContent());
                answer.setFilePath(answerDTO.getFilePath());
                answer.setIsDraft(true);
                answer.setAnswerTime(LocalDateTime.now());
                
                log.info("准备插入的草稿对象 - sessionId: {}, examId: {}, studentId: {}, questionId: {}, isDraft: {}", 
                        answer.getSessionId(), answer.getExamId(), answer.getStudentId(), 
                        answer.getQuestionId(), answer.getIsDraft());
                
                examAnswersMapper.insertExamAnswer(answer);
                log.info("草稿插入完成 - 新生成的answerId: {}", answer.getAnswerId());
            }
            log.info("=== 草稿处理完成 ===");
        }
        
        log.info("答案草稿保存完成 - 考试ID: {}, 学生ID: {}", examId, studentId);
    }

    @Override
    public List<ExamAnswer> getStudentAnswers(Long examId, Long studentId) {
        if (studentId == null) {
            studentId = StpUtil.getLoginIdAsLong();
        }
        return examAnswersMapper.selectAnswersByExamAndStudent(examId, studentId);
    }

    /**
     * 【关键新增】持久化自动判卷结果到 student_grades 表
     */
    private void updateInitialStudentGrade(Long examId, Long studentId, AutoGradingService.AutoGradingResult result) {
        // 检查是否已有成绩记录 (例如，学生重新提交)
        StudentGrade existingGrade = studentGradesMapper.selectGradeByExamAndStudent(examId, studentId);
        
        // 计算试卷总分
        BigDecimal maxScore = examQuestionsMapper.calculateTotalPointsForExam(examId);

        if (existingGrade == null) {
            // 创建新的成绩记录
            StudentGrade newGrade = new StudentGrade();
            newGrade.setExamId(examId);
            newGrade.setUserId(studentId); // 使用userId而不是studentId
            
            // 关键修改：根据是否有主观题设置dispute_status
            // 统一设置为pending状态，无论是否有主观题
            newGrade.setScore(BigDecimal.valueOf(result.getTotalScore()));
            if (result.getManualGradedQuestions() > 0) {
                newGrade.setComments("自动批改完成，等待主观题批改");
                log.info("为学生 {} 创建初始成绩记录，有 {} 道主观题需要人工批改，状态设为pending", 
                        studentId, result.getManualGradedQuestions());
            } else {
                newGrade.setComments("自动批改完成");
                log.info("为学生 {} 创建初始成绩记录，全部客观题，得分: {}，状态设为pending", 
                        studentId, result.getTotalScore());
            }
            newGrade.setDisputeStatus("pending"); // 新提交学生统一设为pending状态
            studentGradesMapper.insertStudentGrade(newGrade);
        } else {
            // 如果允许重新提交，更新现有记录，统一设置为pending状态
            existingGrade.setScore(BigDecimal.valueOf(result.getTotalScore()));
            if (result.getManualGradedQuestions() > 0) {
                existingGrade.setComments("重新提交，自动批改完成，等待主观题批改");
                log.info("更新学生 {} 的初始成绩记录，有 {} 道主观题需要人工批改，状态设为pending", 
                        studentId, result.getManualGradedQuestions());
            } else {
                existingGrade.setComments("重新提交，自动批改完成");
                log.info("更新学生 {} 的初始成绩记录，全部客观题，得分: {}，状态设为pending", 
                        studentId, result.getTotalScore());
            }
            existingGrade.setDisputeStatus("pending"); // 重新提交学生统一设为pending状态
            studentGradesMapper.updateStudentGradeById(existingGrade);
        }
    }
}